#pragma once
#include <string>
#include <optional>
using std::optional;
using std::string;

typedef void (*listenCB)(string listenResponse, void *pUserData);
typedef void (*logCB)(string msg, int logLevel, void *pUserData);

typedef struct tagONVIF_IP_ADDR
{
    bool IPv4Type;     // 地址类型是否是ipv4
    char *IPv4Address; // IPv4Type == true 有效
    char *IPv6Address; // IPv4Type == false 有效

} ONVIF_IP_ADDR;

typedef struct tagONVIF_SET_DNS_PARAM
{
    bool useDHCP; // 是否使用DHCP自动获取DNS的IP地址

    int sizeSearchDomain; // searchDomain的个数
    char **searchDomain;
    int sizeDNSManual; // DNSManual的个数
    ONVIF_IP_ADDR **DNSManual;

} ONVIF_SET_DNS_PARAM;

typedef struct tagONVIF_SET_DYNAMIC_DNS_PARAM
{
    int *type; // enum{0:'NoUpdate', 1:'ClientUpdates', 2:'ServerUpdates'}
    char *name;
    char *TTL; // xsd:duration

} ONVIF_SET_DYNAMIC_DNS_PARAM;

typedef struct tagONVIF_USER
{
    char *userName;
    char *password;
    int *userLevel; // enum{0: Administrator, 1: Operator, 2: User, 3: Anonymous, 4: Extended}

} ONVIF_USER;

typedef struct tagONVIF_SET_USER_PARAM
{
    int sizeUser;
    ONVIF_USER *users;

} ONVIF_SET_USER_PARAM;

typedef struct tagONVIF_SET_SCOPES_PARAM
{
    int sizeScopes;
    char **scopes;

} ONVIF_SET_SCOPES_PARAM;

typedef struct tagONVIF_SET_REMOTE_USER_PARAM
{
    char *userName;
    char *password;
    bool useDerivedPassword;

} ONVIF_SET_REMOTE_USER_PARAM;

typedef struct tagONVIF_SET_NETWORK_DEFAULT_GATEWAY_PARAM
{
    unsigned int sizeIPv4;
    char **IPv4Address;

    unsigned int sizeIPv6;
    char **IPv6Address;

} ONVIF_SET_NETWORK_DEFAULT_GATEWAY_PARAM;

typedef struct tagONVIF_NETWORK_LINK_CONFIGURATION
{
    bool autoNegotiation; // 是否启用自动协商
    int speed;            // 双工速度
    unsigned int duplex;  // enum{0: full, 1:half}，双工模式全双工/半双工

} ONVIF_NETWORK_LINK_CONFIGURATION;

typedef struct tagONVIF_DOT11_CONFIGURATION
{
    char *SSID;   // 802.11 SSID
    int sizeSSID; // SSID长度

    unsigned int mode; // enum{0: 'Ad-hoc', 1: 'Infrastructure', 2: 'Extended'} 802.11 StationMode
    char *alias;       // 别名
    char *priority;

    unsigned int securityMode;      // enum{0: 'None',1: 'WEP',2: 'PSK',3: 'Dot1X',4: 'Extended'}
    unsigned int securityAlgorithm; // enum {0: 'CCMP',1: 'TKIP',2: 'Any',3: 'Extended' }
    char *PSKKey;
    char *PSKPassphrase;
    char *dot1XConfigurationToken;

} ONVIF_DOT11_CONFIGURATION;

typedef struct tagONVIF_SET_NETWORK_INTERFACE_PARAM
{
    char *interfaceToken; // getNetworkInterfaces结果里的token
    bool enable;          // 是否启用该网卡
    int MTU;              // 最大传输单元(设置为-1，则为默认)

    ONVIF_NETWORK_LINK_CONFIGURATION *link; // 连接配置

    bool IPv4Enabled;   // 是否使用IPv4（设置为false时，后续IPv4的设置均无效）
    bool IPv4DHCP;      // IPv4是否启用DHCP（启用后，IPv4地址的手动设置无效）
    int sizeIPv4;       // 手动配置的IPv4的个数
    char **IPv4Address; // 手动配置的IPv4地址数组
    int *IPv4PrefixLen; // 手动配置的IPv4子网掩码长度数组

    bool IPv6Enabled;        // 是否使用IPv6（设置为false时，后续IPv6的设置均无效）
    bool acceptRouterAdvert; // 是否接受路由通告
    unsigned int IPv6DHCP;   // enum{0: Auto, 1: Stateful, 2: Stateless, 3: Off}IPv6 DHCP（启用后，IPv6地址的手动设置无效）
    int sizeIPv6;            // 手动配置的IPv6的个数
    char **IPv6Address;      // 手动配置的IPv6地址数组
    int *IPv6PrefixLen;      // 手动配置的IPv6子网掩码长度数组

    int sizeExtension;                     // 802.11配置的个数
    ONVIF_DOT11_CONFIGURATION **extension; // 802.11的配置数组
} ONVIF_SET_NETWORK_INTERFACE_PARAM;

typedef struct tagONVIF_NETWORK_PROTOCOLS
{
    unsigned int protocolsName; // enum{0: HTTP, 1: HTTPS, 2: RTSP}
    bool enabled;               // 是否启用协议
    int sizePort;               // 协议使用的端口号个数
    int *port;                  // 协议使用的端口号数组

} ONVIF_NETWORK_PROTOCOLS;

typedef struct tagONVIF_SET_NETWORK_PROTOCOLS_PARAM
{
    int sizeProtocols;                   // 待修改的协议个数
    ONVIF_NETWORK_PROTOCOLS **protocols; // 待修改的协议数组
} ONVIF_SET_NETWORK_PROTOCOLS_PARAM;

typedef struct tagONVIF_TRANSPORT_PROTOCOL
{
    unsigned int protocolsName;          // enum{0: UDP,1: TCP,2: RTSP,3: HTTP}
                                         // UDP=RTP/UDP, RTSP=RTP/RTSP/TCP,  HTTP=RTP/RTSP/HTTP/TCP
    tagONVIF_TRANSPORT_PROTOCOL *tunnel; // 可选项，传输协议链，不同网络协议上的隧道化
} ONVIF_TRANSPORT_PROTOCOL;

typedef struct tagONVIF_STREAM_SETUP_PARAM
{
    unsigned int streamType;            // enum{0: RTP-Unicast, 1: RTP-Multicast}
    ONVIF_TRANSPORT_PROTOCOL transport; // 传输协议
} ONVIF_STREAM_SETUP_PARAM;

typedef struct tagONVIF_CONFIGURATION_ENUMERATION
{
    unsigned int *typeArray; // array, item: enum{0: VideoSource, 1: AudioSource, 2: AudioEncoder, 3: Analytics,
                             //                   4: PTZ, 5: Metadata, 6: AudioOutput, 7:AudioDecoder, 8:VideoEncoder}
    char **tokenArray;       // 可选项，array, type对应的configuration的token，在配置profile时才使用到
    unsigned int size;       // arraySize
} ONVIF_CONFIGURATION_ENUMERATION;

typedef struct tagONVIF_TRANSPORT_PROTOCOL_V2
{
    unsigned int protocolsName; // enum{0: RtspUnicast,1: RtspMulticast,2: RTSP,3: RtspsUnicast,4: RtspsMulticast,5: RtspOverHttp}
                                // RtspUnicast:     RTSP streaming RTP via UDP Unicast.
                                // RtspMulticast:   RTSP streaming RTP via UDP Multicast.
                                // RTSP:            RTSP streaming RTP over TCP.
                                // RtspsUnicast:    Secure RTSP streaming SRTP via UDP Unicast.
                                // RtspsMulticast:  Secure RTSP streaming SRTP via UDP Multicast.
                                // RtspOverHttp:    Tunneling both the RTSP control channel and the RTP stream over HTTP or HTTPS.
} ONVIF_TRANSPORT_PROTOCOL_V2;

typedef struct tagONVIF_COLOR
{
    unsigned int colorSpace; // 颜色空间, enum{0: http://www.onvif.org/ver10/colorspace/YCbCr, 1: http://www.onvif.org/ver10/colorspace/CIELUV,
                             // 2: http://www.onvif.org/ver10/colorspace/CIELAB 3: http://www.onvif.org/ver10/colorspace/HSV}
    float x;                 // 颜色的值（x,y,z)
    float y;                 //
    float z;                 //
    float *likelihood;       // 可选

} ONVIF_COLOR;

typedef struct tagONVIF_SET_OSD_PARAM
{
    char *OSDConfigurationToken;
    char *videoSourceConfigurationToken;
    unsigned int type;         // OSD类型 enum{0: Text, 1: Image, 2: Extended}
    unsigned int positionType; // 位置类型 enum{0: UpperLeft, 1: UpperRight, 2: LowerLeft, 3: LowerRight, 4: Custom}
    float *positionX;          // 自定义位置x，范围-1 ~ 1，仅当positionType为Custom有效此时不能是null
    float *positionY;          // 自定义位置y 范围-1 ~ 1，仅当positionType为Custom有效此时不能是null

    // text相关仅当type为Text时有效
    bool *isPersistentText;              // 可选，默认为true，设置文本是否永久保存
    unsigned int textType;               // 文本类型， enum{0: Plain, 1: Date, 2: Time, 3: DateAndTime}
    unsigned int dateFormat;             // 可选，日期格式，仅当textType为Date或DateAndTime有效，enum{0: M/d/yyyy, 1: MM/dd/yyyy, 2: dd/MM/yyyy,
                                         // 3: yyyy/MM/dd, 4: yyyy-MM-dd, 5: "dddd, MMMM dd, yyyy", 6: "MMMM dd, yyyy", 7: "dd MMMM, yyyy"}
    unsigned int timeFormat;             // 可选，时间格式，仅当textType为Time或DateAndTime有效，enum{0: h:mm:ss tt, 1: hh:mm:ss tt,
                                         // 2: H:mm:ss, 3: HH:mm:ss}
    unsigned int *fontSize;              // 可选，单位pt
    ONVIF_COLOR *fontColor;              // 可选, 字体颜色
    unsigned int *fontTransparent;       // 可选， 字体透明度
    ONVIF_COLOR *backgroundColor;        // 可选, 背景颜色
    unsigned int *backgroundTransparent; // 可选， 背景透明度
    char *plainText;                     // 可选，显示的文本，仅当textType为Plain时有效

    // image相关仅当type为Image时有效
    char *imgPath; // 可选，图片路径

} ONVIF_SET_OSD_PARAM;

typedef struct tagONVIF_FIND_RECORDINGS_PARAM
{
    char **includeSourcesToken;              // 可选，源数组，搜索的源范围，设置后，只会搜索该范围内的记录
    int **includeSourcesType;                // 可选，源类型数组，大小与源数组一致，enum{0, http://www.onvif.org/ver10/schema/Profile,
                                             //  1: http://www.onvif.org/ver10/schema/Receiver}, includeSourcesToken存在时includeSourcesType也可为null
    unsigned int includeSourcesTokenSize;    // 源数组大小
    char **includeRecordingsToken;           // 可选，记录的数组，搜索的记录的范围，设置后，只会搜索范围内的记录
    unsigned int includeRecordingsTokenSize; // 记录的数组大小
    char *recordingInformationFilter;        // 可选，xpath表达式，过滤搜索的记录，recordingInformation的结构是onvif协议的 GetRecordingInformation 的返回的结构
                                             // 参考：https://www.w3.org/TR/1999/REC-xpath-19991116/
    int *maxMatches;                         // 可选，最大的匹配数量，设置后，当搜索到的数量达到时停止搜索
    char *keepAliveTime;                     // 该搜索句柄的存活时间，duration格式，例如：一天：P1D、一小时：PT1H
} ONVIF_FIND_RECORDINGS_PARAM;

typedef struct tagONVIF_PTZ_SPEED_PARAM
{
    bool zoomSpeedEnable;   // 是否设置zoom的速度，设为false时，zoom相关参数无效，使用默认速度
    unsigned int zoomSpace; // 缩放速度空间，onvif预定义，enum{
                            // 0: http://www.onvif.org/ver10/tptz/ZoomSpaces/ZoomGenericSpeedSpace,(速度范围0~1，0停止，1最快的速度)
                            // 1：http://www.onvif.org/ver10/tptz/ZoomSpaces/SpeedSpaceMillimeter, (毫米每秒, 速度范围0~inf)
                            // 2：http://www.onvif.org/ver10/tptz/ZoomSpaces/VelocityGenericSpace(范围-1~1, Continuous move时有效)}
    float zoomSpeed;        // 缩放的速度，不同缩放速度空间定义的速度范围不同

    bool panTiltSpeedEnable;   // 是否设置panTilt的速度，设为false时，panTilt相关参数无效， 使用默认速度
    unsigned int panTiltSpace; // 旋转的速度空间，onvif预定义, enum{
                               // 0: http://www.onvif.org/ver10/tptz/PanTiltSpaces/GenericSpeedSpace,(速度范围0~1，0停止，1最快的速度)
                               // 1: http://www.onvif.org/ver10/tptz/PanTiltSpaces/SpeedSpaceDegrees,(角度每秒，速度范围0~inf)
                               // 2: http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace, (位置范围-1~1, Continuous move时有效)
                               // 3: http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocitySpaceDegrees, (单位角度，范围-inf~inf, Continuous move时有效)}
    float panSpeed;            // x方向（水平方向）的速度
    float tiltSpeed;           // y方向（竖直方向）的速度
} ONVIF_PTZ_SPEED_PARAM;

typedef struct tagONVIF_PTZ_MOVE_PARAM
{
    bool zoomEnable;        // 是否设置zoom，设为false时，zoom相关参数无效
    unsigned int zoomSpace; // 缩放空间，onvif预定义，enum{
                            // 0: http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace,(范围0~1，0最小的位置，1最大的位置，Absolute move时有效)
                            // 1：http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionSpaceMillimeter, (单位毫米, 范围0~inf，Absolute move时有效)
                            // 2：http://www.onvif.org/ver10/tptz/ZoomSpaces/TranslationGenericSpace,(范围-1~1, Relative move时有效)}
    float zoomVal;          // 缩放的值，不同缩放空间定义的范围不同

    bool panTiltEnable;        // 是否设置panTilt的位置，设为false时，panTilt相关参数无效
    unsigned int panTiltSpace; // 旋转空间，onvif预定义, enum{
                               // 0: http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace,(位置范围-1~1，Absolute move时有效)
                               // 1: http://www.onvif.org/ver10/tptz/PanTiltSpaces/SphericalPositionSpace,(单位角度，范围-inf~inf，Absolute move时有效)
                               // 2: http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace, (位置范围-1~1, Relative move时有效)}
    float panPos;              // x方向（水平方向）的坐标
    float tiltPos;             // y方向（竖直方向）的坐标

    ONVIF_PTZ_SPEED_PARAM *moveSpeed; // 可选，移动速度
} ONVIF_PTZ_MOVE_PARAM;

typedef struct tagONVIF_FOCUS_MOVE_PARAM
{
    unsigned int direction; // focus 移动的方向，enum{0: auto, 1: near, 2: far}
    char *timeOut;          // 超时时间（持续时间），duration格式，例如：一天：P1D、一小时：PT1H、30秒：PT30S
} ONVIF_FOCUS_MOVE_PARAM;

class IOnvifTool
{
public:
    virtual ~IOnvifTool(){};
    virtual optional<string> init() = 0;
    virtual void printLog(logCB cb, void *pUserData) = 0;

    // send and receive timeout (second)
    virtual void setTimeOut(int timeOutSecond_) = 0;
    virtual optional<string> discoverDevice(string &responseJson) = 0;
    virtual optional<string> listenHello(listenCB cb, void *pUserData) = 0;
    virtual optional<string> stopListenHello() = 0;
    virtual optional<string> listenBye(listenCB cb, void *pUserData) = 0;
    virtual optional<string> stopListenBye() = 0;

    /*---------------addr: http://-------/onvif/device_service ----------------*/
    virtual optional<string> getDeviceInformation(string &responseJson,
                                                  const char *deviceXAddr,
                                                  const char *userName,
                                                  const char *password) = 0;
    virtual optional<string> getServiceCapabilities(string &responseJson,
                                                    const char *deviceXAddr) = 0;
    virtual optional<string> getServices(string &responseJson,
                                         const char *deviceXAddr) = 0;
    virtual optional<string> getDNS(string &responseJson,
                                    const char *deviceXAddr,
                                    const char *userName,
                                    const char *password) = 0;
    virtual optional<string> getDynamicDNS(string &responseJson,
                                           const char *deviceXAddr,
                                           const char *userName,
                                           const char *password) = 0;
    virtual optional<string> getEndpointReference(string &responseJson,
                                                  const char *deviceXAddr) = 0;
    virtual optional<string> getGeoLocation(string &responseJson,
                                            const char *deviceXAddr,
                                            const char *userName,
                                            const char *password) = 0;
    virtual optional<string> getNetworkDefaultGateway(string &responseJson,
                                                      const char *deviceXAddr,
                                                      const char *userName,
                                                      const char *password) = 0;
    virtual optional<string> getNetworkInterfaces(string &responseJson,
                                                  const char *deviceXAddr,
                                                  const char *userName,
                                                  const char *password) = 0;
    virtual optional<string> getNetworkProtocols(string &responseJson,
                                                 const char *deviceXAddr,
                                                 const char *userName,
                                                 const char *password) = 0;
    virtual optional<string> getHostname(string &responseJson,
                                         const char *deviceXAddr) = 0;
    virtual optional<string> getRemoteUser(string &responseJson,
                                           const char *deviceXAddr,
                                           const char *userName,
                                           const char *password) = 0;
    virtual optional<string> getScopes(string &responseJson,
                                       const char *deviceXAddr,
                                       const char *userName,
                                       const char *password) = 0;
    virtual optional<string> getUsers(string &responseJson,
                                      const char *deviceXAddr,
                                      const char *userName,
                                      const char *password) = 0;
    virtual optional<string> getWsdlUrl(string &responseJson,
                                        const char *deviceXAddr) = 0;
    virtual optional<string> getDiscoveryMode(string &responseJson,
                                              const char *deviceXAddr,
                                              const char *userName,
                                              const char *password) = 0;
    virtual optional<string> getRemoteDiscoveryMode(string &responseJson,
                                                    const char *deviceXAddr,
                                                    const char *userName,
                                                    const char *password) = 0;
    virtual optional<string> setDNS(string &responseJson,
                                    const char *deviceXAddr,
                                    const char *userName,
                                    const char *password,
                                    ONVIF_SET_DNS_PARAM *param) = 0;
    virtual optional<string> setDynamicDNS(string &responseJson,
                                           const char *deviceXAddr,
                                           const char *userName,
                                           const char *password,
                                           ONVIF_SET_DYNAMIC_DNS_PARAM *param) = 0;
    virtual optional<string> setHostname(string &responseJson,
                                         const char *deviceXAddr,
                                         const char *userName,
                                         const char *password,
                                         const char *name) = 0;
    virtual optional<string> systemReboot(string &responseJson,
                                          const char *deviceXAddr,
                                          const char *userName,
                                          const char *password) = 0;
    virtual optional<string> setHostnameFromDHCP(string &responseJson,
                                                 const char *deviceXAddr,
                                                 const char *userName,
                                                 const char *password,
                                                 bool useDHCP) = 0;
    virtual optional<string> setUser(string &responseJson,
                                     const char *deviceXAddr,
                                     const char *userName,
                                     const char *password,
                                     ONVIF_SET_USER_PARAM *param) = 0;
    virtual optional<string> setScopes(string &responseJson,
                                       const char *deviceXAddr,
                                       const char *userName,
                                       const char *password,
                                       ONVIF_SET_SCOPES_PARAM *param) = 0;
    virtual optional<string> setRemoteUser(string &responseJson,
                                           const char *deviceXAddr,
                                           const char *userName,
                                           const char *password,
                                           ONVIF_SET_REMOTE_USER_PARAM *param) = 0;
    virtual optional<string> setDiscoveryMode(string &responseJson,
                                              const char *deviceXAddr,
                                              const char *userName,
                                              const char *password,
                                              bool enable) = 0;
    virtual optional<string> setRemoteDiscoveryMode(string &responseJson,
                                                    const char *deviceXAddr,
                                                    const char *userName,
                                                    const char *password,
                                                    bool enable) = 0;
    virtual optional<string> setNetworkDefaultGateway(string &responseJson,
                                                      const char *deviceXAddr,
                                                      const char *userName,
                                                      const char *password,
                                                      ONVIF_SET_NETWORK_DEFAULT_GATEWAY_PARAM *param) = 0;
    virtual optional<string> setNetworkInterfaces(string &responseJson,
                                                  const char *deviceXAddr,
                                                  const char *userName,
                                                  const char *password,
                                                  ONVIF_SET_NETWORK_INTERFACE_PARAM *param) = 0;
    virtual optional<string> setNetworkProtocols(string &responseJson,
                                                 const char *deviceXAddr,
                                                 const char *userName,
                                                 const char *password,
                                                 ONVIF_SET_NETWORK_PROTOCOLS_PARAM *param) = 0;

    /*---------------addr: http://---------/onvif/media_service ----------------*/
    virtual optional<string> getVideoSources_V1(string &responseJson,
                                                const char *deviceXAddr,
                                                const char *userName,
                                                const char *password) = 0;
    virtual optional<string> getVideoSourceConfigurations_V1(string &responseJson,
                                                             const char *deviceXAddr,
                                                             const char *userName,
                                                             const char *password) = 0;
    virtual optional<string> getVideoSourceConfiguration_V1(string &responseJson,
                                                            const char *deviceXAddr,
                                                            const char *userName,
                                                            const char *password,
                                                            const char *configurationToken) = 0;
    virtual optional<string> getVideoSourceConfigurationOptions_V1(string &responseJson,
                                                                   const char *deviceXAddr,
                                                                   const char *userName,
                                                                   const char *password,
                                                                   const char *configurationToken = nullptr,
                                                                   const char *profileToken = nullptr) = 0;
    virtual optional<string> getVideoSourceModes_V1(string &responseJson,
                                                    const char *deviceXAddr,
                                                    const char *userName,
                                                    const char *password,
                                                    const char *videoSourceToken) = 0;
    virtual optional<string> getVideoEncoderConfigurations_V1(string &responseJson,
                                                              const char *deviceXAddr,
                                                              const char *userName,
                                                              const char *password) = 0;
    virtual optional<string> getVideoEncoderConfiguration_V1(string &responseJson,
                                                             const char *deviceXAddr,
                                                             const char *userName,
                                                             const char *password,
                                                             const char *configurationToken) = 0;
    virtual optional<string> getVideoEncoderConfigurationOptions_V1(string &responseJson,
                                                                    const char *deviceXAddr,
                                                                    const char *userName,
                                                                    const char *password,
                                                                    const char *configurationToken = nullptr,
                                                                    const char *profileToken = nullptr) = 0;
    virtual optional<string> getAudioSources_V1(string &responseJson,
                                                const char *deviceXAddr,
                                                const char *userName,
                                                const char *password) = 0;
    virtual optional<string> getAudioSourceConfigurations_V1(string &responseJson,
                                                             const char *deviceXAddr,
                                                             const char *userName,
                                                             const char *password) = 0;
    virtual optional<string> getAudioSourceConfiguration_V1(string &responseJson,
                                                            const char *deviceXAddr,
                                                            const char *userName,
                                                            const char *password,
                                                            const char *configurationToken) = 0;
    virtual optional<string> getAudioSourceConfigurationOptions_V1(string &responseJson,
                                                                   const char *deviceXAddr,
                                                                   const char *userName,
                                                                   const char *password,
                                                                   const char *configurationToken = nullptr,
                                                                   const char *profileToken = nullptr) = 0;
    virtual optional<string> getAudioOutputs_V1(string &responseJson,
                                                const char *deviceXAddr,
                                                const char *userName,
                                                const char *password) = 0;
    virtual optional<string> getAudioOutputConfigurations_V1(string &responseJson,
                                                             const char *deviceXAddr,
                                                             const char *userName,
                                                             const char *password) = 0;
    virtual optional<string> getAudioOutputConfiguration_V1(string &responseJson,
                                                            const char *deviceXAddr,
                                                            const char *userName,
                                                            const char *password,
                                                            const char *configurationToken) = 0;
    virtual optional<string> getAudioOutputConfigurationOptions_V1(string &responseJson,
                                                                   const char *deviceXAddr,
                                                                   const char *userName,
                                                                   const char *password,
                                                                   const char *configurationToken = nullptr,
                                                                   const char *profileToken = nullptr) = 0;
    virtual optional<string> getAudioEncoderConfigurations_V1(string &responseJson,
                                                              const char *deviceXAddr,
                                                              const char *userName,
                                                              const char *password) = 0;
    virtual optional<string> getAudioEncoderConfiguration_V1(string &responseJson,
                                                             const char *deviceXAddr,
                                                             const char *userName,
                                                             const char *password,
                                                             const char *configurationToken) = 0;
    virtual optional<string> getAudioEncoderConfigurationOptions_V1(string &responseJson,
                                                                    const char *deviceXAddr,
                                                                    const char *userName,
                                                                    const char *password,
                                                                    const char *configurationToken = nullptr,
                                                                    const char *profileToken = nullptr) = 0;
    virtual optional<string> getAudioDecoderConfigurations_V1(string &responseJson,
                                                              const char *deviceXAddr,
                                                              const char *userName,
                                                              const char *password) = 0;
    virtual optional<string> getAudioDecoderConfiguration_V1(string &responseJson,
                                                             const char *deviceXAddr,
                                                             const char *userName,
                                                             const char *password,
                                                             const char *configurationToken) = 0;
    virtual optional<string> getAudioDecoderConfigurationOptions_V1(string &responseJson,
                                                                    const char *deviceXAddr,
                                                                    const char *userName,
                                                                    const char *password,
                                                                    const char *configurationToken = nullptr,
                                                                    const char *profileToken = nullptr) = 0;
    virtual optional<string> getMetadataConfigurations_V1(string &responseJson,
                                                          const char *deviceXAddr,
                                                          const char *userName,
                                                          const char *password) = 0;
    virtual optional<string> getMetadataConfiguration_V1(string &responseJson,
                                                         const char *deviceXAddr,
                                                         const char *userName,
                                                         const char *password,
                                                         const char *configurationToken) = 0;
    virtual optional<string> getMetadataConfigurationOptions_V1(string &responseJson,
                                                                const char *deviceXAddr,
                                                                const char *userName,
                                                                const char *password,
                                                                const char *configurationToken = nullptr,
                                                                const char *profileToken = nullptr) = 0;
    virtual optional<string> getVideoAnalyticsConfigurations_V1(string &responseJson,
                                                                const char *deviceXAddr,
                                                                const char *userName,
                                                                const char *password) = 0;
    virtual optional<string> getVideoAnalyticsConfiguration_V1(string &responseJson,
                                                               const char *deviceXAddr,
                                                               const char *userName,
                                                               const char *password,
                                                               const char *configurationToken) = 0;
    virtual optional<string> getProfiles_V1(string &responseJson,
                                            const char *deviceXAddr,
                                            const char *userName,
                                            const char *password) = 0;
    virtual optional<string> getProfile_V1(string &responseJson,
                                           const char *deviceXAddr,
                                           const char *userName,
                                           const char *password,
                                           const char *profileToken) = 0;
    virtual optional<string> createProfile_V1(string &responseJson,
                                              const char *deviceXAddr,
                                              const char *userName,
                                              const char *password,
                                              const char *name,
                                              const char *profileToken = nullptr) = 0;
    virtual optional<string> deleteProfile_V1(string &responseJson,
                                              const char *deviceXAddr,
                                              const char *userName,
                                              const char *password,
                                              const char *profileToken) = 0;
    virtual optional<string> getOSDs_V1(string &responseJson,
                                        const char *deviceXAddr,
                                        const char *userName,
                                        const char *password,
                                        const char *videoSourceConfigurationToken = nullptr) = 0;
    virtual optional<string> getOSD_V1(string &responseJson,
                                       const char *deviceXAddr,
                                       const char *userName,
                                       const char *password,
                                       const char *configurationToken) = 0;
    virtual optional<string> getOSDOptions_V1(string &responseJson,
                                              const char *deviceXAddr,
                                              const char *userName,
                                              const char *password,
                                              const char *videoSourceConfigurationToken) = 0;
    virtual optional<string> createOSD_V1(string &responseJson,
                                          const char *deviceXAddr,
                                          const char *userName,
                                          const char *password,
                                          ONVIF_SET_OSD_PARAM *param) = 0;
    virtual optional<string> deleteOSD_V1(string &responseJson,
                                          const char *deviceXAddr,
                                          const char *userName,
                                          const char *password,
                                          const char *configurationToken) = 0;
    virtual optional<string> setOSD_V1(string &responseJson,
                                       const char *deviceXAddr,
                                       const char *userName,
                                       const char *password,
                                       ONVIF_SET_OSD_PARAM *param) = 0;
    virtual optional<string> getStreamUri_V1(string &responseJson,
                                             const char *deviceXAddr,
                                             const char *userName,
                                             const char *password,
                                             const char *profileToken,
                                             ONVIF_STREAM_SETUP_PARAM *streamSetup) = 0;
    virtual optional<string> getSnapshotUri_V1(string &responseJson,
                                               const char *deviceXAddr,
                                               const char *userName,
                                               const char *password,
                                               const char *profileToken) = 0;
    virtual optional<string> startMulticastStreaming_V1(string &responseJson,
                                                        const char *deviceXAddr,
                                                        const char *userName,
                                                        const char *password,
                                                        const char *profileToken) = 0;
    virtual optional<string> stopMulticastStreaming_V1(string &responseJson,
                                                       const char *deviceXAddr,
                                                       const char *userName,
                                                       const char *password,
                                                       const char *profileToken) = 0;
    virtual optional<string> addVideoSourceConfiguration_V1(string &responseJson,
                                                            const char *deviceXAddr,
                                                            const char *userName,
                                                            const char *password,
                                                            const char *configurationToken,
                                                            const char *profileToken) = 0;
    virtual optional<string> removeVideoSourceConfiguration_V1(string &responseJson,
                                                               const char *deviceXAddr,
                                                               const char *userName,
                                                               const char *password,
                                                               const char *profileToken) = 0;
    virtual optional<string> addVideoEncoderConfiguration_V1(string &responseJson,
                                                             const char *deviceXAddr,
                                                             const char *userName,
                                                             const char *password,
                                                             const char *configurationToken,
                                                             const char *profileToken) = 0;
    virtual optional<string> removeVideoEncoderConfiguration_V1(string &responseJson,
                                                                const char *deviceXAddr,
                                                                const char *userName,
                                                                const char *password,
                                                                const char *profileToken) = 0;
    virtual optional<string> addAudioSourceConfiguration_V1(string &responseJson,
                                                            const char *deviceXAddr,
                                                            const char *userName,
                                                            const char *password,
                                                            const char *configurationToken,
                                                            const char *profileToken) = 0;
    virtual optional<string> removeAudioSourceConfiguration_V1(string &responseJson,
                                                               const char *deviceXAddr,
                                                               const char *userName,
                                                               const char *password,
                                                               const char *profileToken) = 0;
    virtual optional<string> addAudioOutputConfiguration_V1(string &responseJson,
                                                            const char *deviceXAddr,
                                                            const char *userName,
                                                            const char *password,
                                                            const char *configurationToken,
                                                            const char *profileToken) = 0;
    virtual optional<string> removeAudioOutputConfiguration_V1(string &responseJson,
                                                               const char *deviceXAddr,
                                                               const char *userName,
                                                               const char *password,
                                                               const char *profileToken) = 0;
    virtual optional<string> addAudioEncoderConfiguration_V1(string &responseJson,
                                                             const char *deviceXAddr,
                                                             const char *userName,
                                                             const char *password,
                                                             const char *configurationToken,
                                                             const char *profileToken) = 0;
    virtual optional<string> removeAudioEncoderConfiguration_V1(string &responseJson,
                                                                const char *deviceXAddr,
                                                                const char *userName,
                                                                const char *password,
                                                                const char *profileToken) = 0;
    virtual optional<string> addAudioDecoderConfiguration_V1(string &responseJson,
                                                             const char *deviceXAddr,
                                                             const char *userName,
                                                             const char *password,
                                                             const char *configurationToken,
                                                             const char *profileToken) = 0;
    virtual optional<string> removeAudioDecoderConfiguration_V1(string &responseJson,
                                                                const char *deviceXAddr,
                                                                const char *userName,
                                                                const char *password,
                                                                const char *profileToken) = 0;
    virtual optional<string> addMetadataConfiguration_V1(string &responseJson,
                                                         const char *deviceXAddr,
                                                         const char *userName,
                                                         const char *password,
                                                         const char *configurationToken,
                                                         const char *profileToken) = 0;
    virtual optional<string> removeMetadataConfiguration_V1(string &responseJson,
                                                            const char *deviceXAddr,
                                                            const char *userName,
                                                            const char *password,
                                                            const char *profileToken) = 0;
    virtual optional<string> addVideoAnalyticsConfiguration_V1(string &responseJson,
                                                               const char *deviceXAddr,
                                                               const char *userName,
                                                               const char *password,
                                                               const char *configurationToken,
                                                               const char *profileToken) = 0;
    virtual optional<string> removeVideoAnalyticsConfiguration_V1(string &responseJson,
                                                                  const char *deviceXAddr,
                                                                  const char *userName,
                                                                  const char *password,
                                                                  const char *profileToken) = 0;
    virtual optional<string> addPTZConfiguration_V1(string &responseJson,
                                                    const char *deviceXAddr,
                                                    const char *userName,
                                                    const char *password,
                                                    const char *configurationToken,
                                                    const char *profileToken) = 0;
    virtual optional<string> removePTZConfiguration_V1(string &responseJson,
                                                       const char *deviceXAddr,
                                                       const char *userName,
                                                       const char *password,
                                                       const char *profileToken) = 0;
    /*---------------addr: http://---------/onvif/media2_service ----------------*/
    virtual optional<string> getVideoSourceConfigurations_V2(string &responseJson,
                                                             const char *deviceXAddr,
                                                             const char *userName,
                                                             const char *password,
                                                             const char *configurationToken = nullptr,
                                                             const char *profileToken = nullptr) = 0;
    virtual optional<string> getVideoSourceConfigurationOptions_V2(string &responseJson,
                                                                   const char *deviceXAddr,
                                                                   const char *userName,
                                                                   const char *password,
                                                                   const char *configurationToken = nullptr,
                                                                   const char *profileToken = nullptr) = 0;
    virtual optional<string> getVideoSourceModes_V2(string &responseJson,
                                                    const char *deviceXAddr,
                                                    const char *userName,
                                                    const char *password,
                                                    const char *videoSourceToken) = 0;
    virtual optional<string> getVideoEncoderInstances_V2(string &responseJson,
                                                         const char *deviceXAddr,
                                                         const char *userName,
                                                         const char *password,
                                                         const char *videoSourceConfigurationToken) = 0;
    virtual optional<string> getVideoEncoderConfigurations_V2(string &responseJson,
                                                              const char *deviceXAddr,
                                                              const char *userName,
                                                              const char *password,
                                                              const char *configurationToken = nullptr,
                                                              const char *profileToken = nullptr) = 0;
    virtual optional<string> getVideoEncoderConfigurationOptions_V2(string &responseJson,
                                                                    const char *deviceXAddr,
                                                                    const char *userName,
                                                                    const char *password,
                                                                    const char *configurationToken = nullptr,
                                                                    const char *profileToken = nullptr) = 0;
    virtual optional<string> getAudioSourceConfigurations_V2(string &responseJson,
                                                             const char *deviceXAddr,
                                                             const char *userName,
                                                             const char *password,
                                                             const char *configurationToken = nullptr,
                                                             const char *profileToken = nullptr) = 0;
    virtual optional<string> getAudioSourceConfigurationOptions_V2(string &responseJson,
                                                                   const char *deviceXAddr,
                                                                   const char *userName,
                                                                   const char *password,
                                                                   const char *configurationToken = nullptr,
                                                                   const char *profileToken = nullptr) = 0;
    virtual optional<string> getAudioOutputConfigurations_V2(string &responseJson,
                                                             const char *deviceXAddr,
                                                             const char *userName,
                                                             const char *password,
                                                             const char *configurationToken = nullptr,
                                                             const char *profileToken = nullptr) = 0;
    virtual optional<string> getAudioOutputConfigurationOptions_V2(string &responseJson,
                                                                   const char *deviceXAddr,
                                                                   const char *userName,
                                                                   const char *password,
                                                                   const char *configurationToken = nullptr,
                                                                   const char *profileToken = nullptr) = 0;
    virtual optional<string> getAudioEncoderConfigurations_V2(string &responseJson,
                                                              const char *deviceXAddr,
                                                              const char *userName,
                                                              const char *password,
                                                              const char *configurationToken = nullptr,
                                                              const char *profileToken = nullptr) = 0;
    virtual optional<string> getAudioEncoderConfigurationOptions_V2(string &responseJson,
                                                                    const char *deviceXAddr,
                                                                    const char *userName,
                                                                    const char *password,
                                                                    const char *configurationToken = nullptr,
                                                                    const char *profileToken = nullptr) = 0;
    virtual optional<string> getAudioDecoderConfigurations_V2(string &responseJson,
                                                              const char *deviceXAddr,
                                                              const char *userName,
                                                              const char *password,
                                                              const char *configurationToken = nullptr,
                                                              const char *profileToken = nullptr) = 0;
    virtual optional<string> getAudioDecoderConfigurationOptions_V2(string &responseJson,
                                                                    const char *deviceXAddr,
                                                                    const char *userName,
                                                                    const char *password,
                                                                    const char *configurationToken = nullptr,
                                                                    const char *profileToken = nullptr) = 0;
    virtual optional<string> getMetadataConfigurations_V2(string &responseJson,
                                                          const char *deviceXAddr,
                                                          const char *userName,
                                                          const char *password,
                                                          const char *configurationToken = nullptr,
                                                          const char *profileToken = nullptr) = 0;
    virtual optional<string> getMetadataConfigurationOptions_V2(string &responseJson,
                                                                const char *deviceXAddr,
                                                                const char *userName,
                                                                const char *password,
                                                                const char *configurationToken = nullptr,
                                                                const char *profileToken = nullptr) = 0;
    virtual optional<string> getAnalyticsConfigurations_V2(string &responseJson,
                                                           const char *deviceXAddr,
                                                           const char *userName,
                                                           const char *password,
                                                           const char *configurationToken = nullptr,
                                                           const char *profileToken = nullptr) = 0;
    virtual optional<string> getProfiles_V2(string &responseJson,
                                            const char *deviceXAddr,
                                            const char *userName,
                                            const char *password,
                                            const char *profileToken = nullptr,
                                            ONVIF_CONFIGURATION_ENUMERATION *type = nullptr) = 0;
    virtual optional<string> createProfile_V2(string &responseJson,
                                              const char *deviceXAddr,
                                              const char *userName,
                                              const char *password,
                                              const char *name) = 0;
    virtual optional<string> deleteProfile_V2(string &responseJson,
                                              const char *deviceXAddr,
                                              const char *userName,
                                              const char *password,
                                              const char *profileToken) = 0;
    virtual optional<string> getOSDs_V2(string &responseJson,
                                        const char *deviceXAddr,
                                        const char *userName,
                                        const char *password,
                                        const char *videoSourceConfigurationToken = nullptr,
                                        const char *OSDToken = nullptr) = 0;
    virtual optional<string> getOSDOptions_V2(string &responseJson,
                                              const char *deviceXAddr,
                                              const char *userName,
                                              const char *password,
                                              const char *videoSourceConfigurationToken) = 0;
    virtual optional<string> createOSD_V2(string &responseJson,
                                          const char *deviceXAddr,
                                          const char *userName,
                                          const char *password,
                                          ONVIF_SET_OSD_PARAM *param) = 0;
    virtual optional<string> deleteOSD_V2(string &responseJson,
                                          const char *deviceXAddr,
                                          const char *userName,
                                          const char *password,
                                          const char *configurationToken) = 0;
    virtual optional<string> setOSD_V2(string &responseJson,
                                       const char *deviceXAddr,
                                       const char *userName,
                                       const char *password,
                                       ONVIF_SET_OSD_PARAM *param) = 0;
    virtual optional<string> getMasks_V2(string &responseJson,
                                         const char *deviceXAddr,
                                         const char *userName,
                                         const char *password,
                                         const char *videoSourceConfigurationToken = nullptr,
                                         const char *maskToken = nullptr) = 0;
    virtual optional<string> getMaskOptions_V2(string &responseJson,
                                               const char *deviceXAddr,
                                               const char *userName,
                                               const char *password,
                                               const char *videoSourceConfigurationToken) = 0;
    virtual optional<string> getStreamUri_V2(string &responseJson,
                                             const char *deviceXAddr,
                                             const char *userName,
                                             const char *password,
                                             const char *profileToken,
                                             ONVIF_TRANSPORT_PROTOCOL_V2 protocol) = 0;
    virtual optional<string> getSnapshotUri_V2(string &responseJson,
                                               const char *deviceXAddr,
                                               const char *userName,
                                               const char *password,
                                               const char *profileToken) = 0;
    virtual optional<string> startMulticastStreaming_V2(string &responseJson,
                                                        const char *deviceXAddr,
                                                        const char *userName,
                                                        const char *password,
                                                        const char *profileToken) = 0;
    virtual optional<string> stopMulticastStreaming_V2(string &responseJson,
                                                       const char *deviceXAddr,
                                                       const char *userName,
                                                       const char *password,
                                                       const char *profileToken) = 0;
    virtual optional<string> addConfiguration_V2(string &responseJson,
                                                 const char *deviceXAddr,
                                                 const char *userName,
                                                 const char *password,
                                                 const char *profileToken,
                                                 ONVIF_CONFIGURATION_ENUMERATION *configurations) = 0;
    virtual optional<string> removeConfiguration_V2(string &responseJson,
                                                    const char *deviceXAddr,
                                                    const char *userName,
                                                    const char *password,
                                                    const char *profileToken,
                                                    ONVIF_CONFIGURATION_ENUMERATION *configurations) = 0;

    /*---------------addr: http://---------/onvif/deviceIO_service ----------------*/
    virtual optional<string> getVideoOutputs_DeviceIO(string &responseJson,
                                                      const char *deviceXAddr,
                                                      const char *userName,
                                                      const char *password) = 0;
    virtual optional<string> getVideoSources_DeviceIO(string &responseJson,
                                                      const char *deviceXAddr,
                                                      const char *userName,
                                                      const char *password) = 0;
    virtual optional<string> getVideoOutputConfiguration_DeviceIO(string &responseJson,
                                                                  const char *deviceXAddr,
                                                                  const char *userName,
                                                                  const char *password,
                                                                  const char *videoOutputToken) = 0;
    virtual optional<string> getVideoOutputConfigurationOptions_DeviceIO(string &responseJson,
                                                                         const char *deviceXAddr,
                                                                         const char *userName,
                                                                         const char *password,
                                                                         const char *videoOutputToken) = 0;
    virtual optional<string> getVideoSourceConfiguration_DeviceIO(string &responseJson,
                                                                  const char *deviceXAddr,
                                                                  const char *userName,
                                                                  const char *password,
                                                                  const char *videoSourceToken) = 0;
    virtual optional<string> getVideoSourceConfigurationOptions_DeviceIO(string &responseJson,
                                                                         const char *deviceXAddr,
                                                                         const char *userName,
                                                                         const char *password,
                                                                         const char *videoSourceToken) = 0;
    virtual optional<string> getAudioOutputs_DeviceIO(string &responseJson,
                                                      const char *deviceXAddr,
                                                      const char *userName,
                                                      const char *password) = 0;
    virtual optional<string> getAudioSources_DeviceIO(string &responseJson,
                                                      const char *deviceXAddr,
                                                      const char *userName,
                                                      const char *password) = 0;
    virtual optional<string> getAudioOutputConfiguration_DeviceIO(string &responseJson,
                                                                  const char *deviceXAddr,
                                                                  const char *userName,
                                                                  const char *password,
                                                                  const char *audioOutputToken) = 0;
    virtual optional<string> getAudioOutputConfigurationOptions_DeviceIO(string &responseJson,
                                                                         const char *deviceXAddr,
                                                                         const char *userName,
                                                                         const char *password,
                                                                         const char *audioOutputToken) = 0;
    virtual optional<string> getAudioSourceConfiguration_DeviceIO(string &responseJson,
                                                                  const char *deviceXAddr,
                                                                  const char *userName,
                                                                  const char *password,
                                                                  const char *audioSourceToken) = 0;
    virtual optional<string> getAudioSourceConfigurationOptions_DeviceIO(string &responseJson,
                                                                         const char *deviceXAddr,
                                                                         const char *userName,
                                                                         const char *password,
                                                                         const char *audioSourceToken) = 0;

    /*---------------addr: http://---------/onvif/ptz_service ----------------*/
    virtual optional<string> getNodes(string &responseJson,
                                      const char *deviceXAddr,
                                      const char *userName,
                                      const char *password) = 0;
    virtual optional<string> getNode(string &responseJson,
                                     const char *deviceXAddr,
                                     const char *userName,
                                     const char *password,
                                     const char *nodeToken) = 0;
    virtual optional<string> getPTZConfigurations(string &responseJson,
                                                  const char *deviceXAddr,
                                                  const char *userName,
                                                  const char *password) = 0;
    virtual optional<string> getPTZConfiguration(string &responseJson,
                                                 const char *deviceXAddr,
                                                 const char *userName,
                                                 const char *password,
                                                 const char *configurationToken) = 0;
    virtual optional<string> getPTZConfigurationOptions(string &responseJson,
                                                        const char *deviceXAddr,
                                                        const char *userName,
                                                        const char *password,
                                                        const char *configurationToken) = 0;
    virtual optional<string> getPTZStatus(string &responseJson,
                                          const char *deviceXAddr,
                                          const char *userName,
                                          const char *password,
                                          const char *profileToken) = 0;
    virtual optional<string> absoluteMove(string &responseJson,
                                          const char *deviceXAddr,
                                          const char *userName,
                                          const char *password,
                                          const char *profileToken,
                                          ONVIF_PTZ_MOVE_PARAM *move) = 0;
    virtual optional<string> relativeMove(string &responseJson,
                                          const char *deviceXAddr,
                                          const char *userName,
                                          const char *password,
                                          const char *profileToken,
                                          ONVIF_PTZ_MOVE_PARAM *move) = 0;
    virtual optional<string> continuousMove(string &responseJson,
                                            const char *deviceXAddr,
                                            const char *userName,
                                            const char *password,
                                            const char *profileToken,
                                            ONVIF_PTZ_SPEED_PARAM *speed,
                                            const char *timeOutDuration = nullptr) = 0;
    virtual optional<string> stopMove(string &responseJson,
                                      const char *deviceXAddr,
                                      const char *userName,
                                      const char *password,
                                      const char *profileToken,
                                      bool panTilt = true,
                                      bool zoom = true) = 0;
    virtual optional<string> getPresets(string &responseJson,
                                        const char *deviceXAddr,
                                        const char *userName,
                                        const char *password,
                                        const char *profileToken) = 0;
    virtual optional<string> gotoHomePosition(string &responseJson,
                                              const char *deviceXAddr,
                                              const char *userName,
                                              const char *password,
                                              const char *profileToken,
                                              ONVIF_PTZ_SPEED_PARAM *speed = nullptr) = 0;
    virtual optional<string> setHomePosition(string &responseJson,
                                             const char *deviceXAddr,
                                             const char *userName,
                                             const char *password,
                                             const char *profileTokenr) = 0;
    virtual optional<string> gotoPreset(string &responseJson,
                                        const char *deviceXAddr,
                                        const char *userName,
                                        const char *password,
                                        const char *profileToken,
                                        const char *presetToken,
                                        ONVIF_PTZ_SPEED_PARAM *speed = nullptr) = 0;
    virtual optional<string> setPreset(string &responseJson,
                                       const char *deviceXAddr,
                                       const char *userName,
                                       const char *password,
                                       const char *profileToken,
                                       const char *presetToken,
                                       const char *presetName = nullptr) = 0;
    virtual optional<string> addPreset(string &responseJson,
                                       const char *deviceXAddr,
                                       const char *userName,
                                       const char *password,
                                       const char *profileToken,
                                       const char *presetName) = 0;
    virtual optional<string> removePreset(string &responseJson,
                                          const char *deviceXAddr,
                                          const char *userName,
                                          const char *password,
                                          const char *profileToken,
                                          const char *presetToken) = 0;

    /*---------------addr: http://---------/onvif/recording_service ----------------*/

    /*---------------addr: http://---------/onvif/search_service ----------------*/
    virtual optional<string> getRecordingSummary(string &responseJson,
                                                 const char *deviceXAddr,
                                                 const char *userName,
                                                 const char *password) = 0;
    virtual optional<string> findRecordings(string &responseJson,
                                            const char *deviceXAddr,
                                            const char *userName,
                                            const char *password,
                                            ONVIF_FIND_RECORDINGS_PARAM *param) = 0;
    virtual optional<string> getRecordingInformation(string &responseJson,
                                                     const char *deviceXAddr,
                                                     const char *userName,
                                                     const char *password,
                                                     const char *recordingToken) = 0;
    virtual optional<string> getRecordingSearchResults(string &responseJson,
                                                       const char *deviceXAddr,
                                                       const char *userName,
                                                       const char *password,
                                                       const char *searchToken,
                                                       const int *minResults = nullptr,
                                                       const int *maxResults = nullptr,
                                                       const char *waitDuration = nullptr) = 0;
    virtual optional<string> endSearch(string &responseJson,
                                       const char *deviceXAddr,
                                       const char *userName,
                                       const char *password,
                                       const char *searchTokenr) = 0;

    /*---------------addr: http://---------/onvif/replay_service ----------------*/
    virtual optional<string> getReplayUri(string &responseJson,
                                          const char *deviceXAddr,
                                          const char *userName,
                                          const char *password,
                                          const char *recordingToken,
                                          ONVIF_STREAM_SETUP_PARAM *streamSetup) = 0;

    /*---------------addr: http://---------/onvif/provisioning_service ----------------*/
    virtual optional<string> focusMove(string &responseJson,
                                       const char *deviceXAddr,
                                       const char *userName,
                                       const char *password,
                                       const char *videoSourceToken,
                                       ONVIF_FOCUS_MOVE_PARAM *moveParam) = 0;
    virtual optional<string> stopFocusMove(string &responseJson,
                                           const char *deviceXAddr,
                                           const char *userName,
                                           const char *password,
                                           const char *videoSourceToken) = 0;

    /*---------------addr: http://---------/onvif/imaging_service ----------------*/
    virtual optional<string> focusMove_Imaging(string &responseJson,
                                               const char *deviceXAddr,
                                               const char *userName,
                                               const char *password,
                                               const char *videoSourceToken,
                                               float focusSpeed) = 0;
    virtual optional<string> stopFocusMove_Imaging(string &responseJson,
                                                   const char *deviceXAddr,
                                                   const char *userName,
                                                   const char *password,
                                                   const char *videoSourceToken) = 0;
};

IOnvifTool *createOnvifTool();
void deleteOnvifTool(IOnvifTool *instance);